﻿using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public class BattleOrderContrller : BattleRenderBaseController
    {
        private UIBattleInput input { get; set; }
        private UIBattlePad pad { get; set; }
        private Vector2 lastJoystickDir;
        private Vector2 lastSkillJoystickDir;
        private int lastSkillID;

        private bool uiShow;

        public override async UniTask Initialize(BattleRenderContrller rRenderCtrl)
        {
            await base.Initialize(rRenderCtrl);
            await ManagerCenter.UI.ShowWindowAsync<UIBattleInput>();
            this.input = ManagerCenter.UI.GetEntityUI<UIBattleInput>();

            this.input.AddJoystickListener(this.OnJoystickMove, this.OnJoystickUp);
            this.input.AddSkillSlotListener(this.OnSkillJoystickMove, this.OnSkillJoystickUp);
            this.input.AddStanBy(this.OnStanBy);
            await ManagerCenter.UI.ShowWindowAsync<UIBattlePad>();
            this.pad = ManagerCenter.UI.GetEntityUI<UIBattlePad>();

            await ManagerCenter.UI.ShowWindowAsync<UILightDialog>();
            
            this.uiShow = true;
        }

        public void RefreshSkill(SkillViewComponent rComp)
        {
            this.input.RefreshSkillBtn(rComp);
            this.pad.RefreshHeroHead(rComp.unit);
        }

        public void ShowUI(bool isShow)
        {
            if (this.uiShow != isShow)
            {
                this.uiShow = isShow;
                if (this.uiShow)
                {
                    this.pad.ShowPanel();
                    this.input.ShowPanel();
                }
                else
                {
                    this.pad.HidePanel();
                    this.input.HidePanel();
                }
            }
        }

        public void ShowInput(bool isShow)
        {
            if (this.uiShow)
            {
                if (isShow)
                {
                    this.input.ShowPanel();
                }
                else
                {
                    this.input.HidePanel();
                }
            }
        }
        
        private void OnJoystickMove(Vector2 dir)
        {
            if (this.lastJoystickDir != dir && this.mCtrl.queueCtrl.InWaitCastSkill(out var rWait) && rWait != null)
            {
                var rUnit = this.mCtrl.data.GetUnit(rWait.executerID);
                var rOrderComp = rUnit.GetComponent<PlayerOrderComponent>(ETComponentType.PlayerOrderComponent);
                if (rOrderComp == null)
                {
                    return;
                }
                var rOrder = ClassPool.Get<PlayerMoveStartCommand>();
                rOrder.Initialize(dir);
                rOrderComp.CollectCommand(rOrder);

                this.lastJoystickDir = dir;
            }
        }

        private void OnJoystickUp()
        {
            if (this.mCtrl.queueCtrl.InWaitCastSkill(out var rWait) && rWait != null)
            {
                var rUnit = this.mCtrl.data.GetUnit(rWait.executerID);
                var rOrderComp = rUnit.GetComponent<PlayerOrderComponent>(ETComponentType.PlayerOrderComponent);
                var rOrder = ClassPool.Get<PlayerMoveEndCommand>();
                rOrderComp.CollectCommand(rOrder);
            }
            this.lastJoystickDir = Vector2.zero;
        }

        private void OnSkillJoystickMove(int nSkillID, Vector2 dir)
        {
            if ((this.lastSkillID != nSkillID || this.lastSkillJoystickDir != dir) && this.mCtrl.queueCtrl.InWaitCastSkill(out var rWait) && rWait != null)
            {
                var rUnit = this.mCtrl.data.GetUnit(rWait.executerID);
                var rOrderComp = rUnit.GetComponent<PlayerOrderComponent>(ETComponentType.PlayerOrderComponent);
                var rOrder = ClassPool.Get<PlayerSkillMoveCommand>();
                rOrder.Initialize(dir, nSkillID);
                rOrderComp.CollectCommand(rOrder);

                this.lastSkillJoystickDir = dir;
            }
        }

        private void OnSkillJoystickUp(int nSkillID, bool bCancel)
        {
            if (this.mCtrl.queueCtrl.InWaitCastSkill(out var rWait) && rWait != null)
            {
                var rUnit = this.mCtrl.data.GetUnit(rWait.executerID);
                var rOrderComp = rUnit.GetComponent<PlayerOrderComponent>(ETComponentType.PlayerOrderComponent);
                // 先来一个停止命令停止移动，再放技能
                var rStop = ClassPool.Get<PlayerMoveEndCommand>();
                rOrderComp.CollectCommand(rStop);
                // 再释放技能
                var rOrder = ClassPool.Get<PlayerSkillCommand>();
                rOrder.Initialize(nSkillID, bCancel);
                rOrderComp.CollectCommand(rOrder);
            }
            this.lastSkillID = -1;
            this.lastSkillJoystickDir = Vector2.zero;
        }

        private void OnStanBy()
        {
            if (this.mCtrl.queueCtrl.InWaitCastSkill(out var rWait) && rWait != null)
            {
                var rUnit = this.mCtrl.data.GetUnit(rWait.executerID);
                var rOrderComp = rUnit.GetComponent<PlayerOrderComponent>(ETComponentType.PlayerOrderComponent);
                // 先来一个停止命令停止移动，再放技能
                var rStop = ClassPool.Get<PlayerMoveEndCommand>();
                rOrderComp.CollectCommand(rStop);
                // 再释放 空技能 表示待机
                var rOrder = ClassPool.Get<PlayerSkillCommand>();
                rOrder.Initialize(0, false);
                rOrderComp.CollectCommand(rOrder);
            }
            this.lastSkillID = -1;
            this.lastSkillJoystickDir = Vector2.zero;
        }

        protected override void OnDispose()
        {
            base.OnDispose();
            ManagerCenter.UI.CloseWindow<UIBattleInput>();
            ManagerCenter.UI.CloseWindow<UIBattlePad>();
            this.input = null;
            this.pad = null;
        }
    }
}